{
  "nbformat_minor": 0,
  "nbformat": 4,
  "cells": [
    {
      "source": [
        "#### Copyright 2017 Google LLC."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "copyright-notice"
      }
    },
    {
      "execution_count": 0,
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "copyright-notice2",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        },
        "cellView": "both"
      },
      "source": [
        "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ],
      "outputs": []
    },
    {
      "source": [
        " # Creaci\u00f3n y manipulaci\u00f3n de tensores"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "P0bQXjp499sl"
      }
    },
    {
      "source": [
        " **Objetivos de aprendizaje:**\n",
        "  * inicializar y asignar las variables de TensorFlow\n",
        "  * crear y manipular tensores\n",
        "  * repasar la suma y el producto en \u00e1lgebra lineal (si estos temas son nuevos para ti, consulta una introducci\u00f3n a la [suma](https://es.wikipedia.org/wiki/Adici\u00f3n_matricial) y el [producto](https://es.wikipedia.org/wiki/Multiplicaci\u00f3n_de_matrices)\n",
        "  * familiarizarte con operaciones b\u00e1sicas de matem\u00e1tica y matrices de TensorFlow"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "I3BCiWJiCGsv"
      }
    },
    {
      "source": [
        "from __future__ import print_function\n\n",
        "import tensorflow as tf"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "85evKRsOIC5a",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " ## Suma de vectores\n",
        "\n",
        "Puedes realizar muchas operaciones matem\u00e1ticas en los tensores ([TF API](https://www.tensorflow.org/api_guides/python/math_ops)). El siguiente c\u00f3digo crea y manipula dos vectores (tensores 1-D), cada uno con seis elementos:"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "PT1sorfH-DdQ"
      }
    },
    {
      "source": [
        "with tf.Graph().as_default():\n",
        "  # Create a six-element vector (1-D tensor).\n",
        "  primes = tf.constant([2, 3, 5, 7, 11, 13], dtype=tf.int32)\n",
        "\n",
        "  # Create another six-element vector. Each element in the vector will be\n",
        "  # initialized to 1. The first argument is the shape of the tensor (more\n",
        "  # on shapes below).\n",
        "  ones = tf.ones([6], dtype=tf.int32)\n",
        "\n",
        "  # Add the two vectors. The resulting tensor is a six-element vector.\n",
        "  just_beyond_primes = tf.add(primes, ones)\n",
        "\n",
        "  # Create a session to run the default graph.\n",
        "  with tf.Session() as sess:\n",
        "    print(just_beyond_primes.eval())"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "ng37e6ur-GZo",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " ### Formas de tensores\n",
        "\n",
        "Las formas se usan para describir el tama\u00f1o y la cantidad de dimensiones de un tensor. La forma de un tensor se expresa como `list`, donde el elemento con \u00edndice `i` representa el tama\u00f1o en la dimensi\u00f3n `i`. La longitud de la lista indica la clasificaci\u00f3n del tensor (p. ej., la cantidad de dimensiones).\n",
        "\n",
        "Para obtener m\u00e1s informaci\u00f3n, consulta la [documentaci\u00f3n de TensorFlow](https://www.tensorflow.org/programmers_guide/tensors#shape).\n",
        "\n",
        "Algunos ejemplos b\u00e1sicos:"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "fVvaXzzMGZid"
      }
    },
    {
      "source": [
        "with tf.Graph().as_default():\n",
        "  # A scalar (0-D tensor).\n",
        "  scalar = tf.zeros([])\n",
        "\n",
        "  # A vector with 3 elements.\n",
        "  vector = tf.zeros([3])\n",
        "\n",
        "  # A matrix with 2 rows and 3 columns.\n",
        "  matrix = tf.zeros([2, 3])\n",
        "\n",
        "  with tf.Session() as sess:\n",
        "    print('scalar has shape', scalar.get_shape(), 'and value:\\n', scalar.eval())\n",
        "    print('vector has shape', vector.get_shape(), 'and value:\\n', vector.eval())\n",
        "    print('matrix has shape', matrix.get_shape(), 'and value:\\n', matrix.eval())\n"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "PWzvJnIAH_cF",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " ### Emisi\u00f3n\n",
        "\n",
        "En t\u00e9rminos matem\u00e1ticos, solo puedes realizar operaciones basadas en elementos (p. ej., *suma* e *iguales*) en los tensores de la misma forma. Sin embargo, en TensorFlow, puedes realizar operaciones en tensores que tradicionalmente eran incompatibles. TensorFlow es compatible con la **emisi\u00f3n** (un concepto acu\u00f1ado de NumPy), donde la matriz m\u00e1s peque\u00f1a en una operaci\u00f3n basada en elementos se ampl\u00eda para que tenga la misma forma que la matriz m\u00e1s grande. Por ejemplo, mediante la emisi\u00f3n:\n",
        "\n",
        "* Si un operando requiere un tensor de tama\u00f1o `[6]`, un tensor de tama\u00f1o `[1]` o `[]` puede servir como operando.\n",
        "* Si un operando requiere un tensor de tama\u00f1o `[4, 6]`, cualquiera de los siguientes tama\u00f1os puede servir como operando:\n",
        "  * `[1, 6]`\n",
        "  * `[6]`\n",
        "  * `[]`\n",
        "* Si una operaci\u00f3n requiere un tensor de tama\u00f1o `[3, 5, 6]`, cualquiera de los siguientes tama\u00f1os puede servir como operando:\n",
        "\n",
        "  * `[1, 5, 6]`\n",
        "  * `[3, 1, 6]`\n",
        "  * `[3, 5, 1]`\n",
        "  * `[1, 1, 1]`\n",
        "  * `[5, 6]`\n",
        "  * `[1, 6]`\n",
        "  * `[6]`\n",
        "  * `[1]`\n",
        "  * `[]`\n",
        "  \n",
        "**NOTA:** Cuando un tensor es de emisi\u00f3n, sus entradas se **copian** conceptualmente. (Por cuestiones de rendimiento, no se copian realmente; la emisi\u00f3n se cre\u00f3 como una optimizaci\u00f3n del rendimiento).\n",
        "\n",
        "El conjunto de reglas completo de la emisi\u00f3n se describe en detalle en la [documentaci\u00f3n sobre la emisi\u00f3n de NumPy](http://docs.scipy.org/doc/numpy-1.10.1/user/basics.broadcasting.html).\n",
        "\n",
        "El siguiente c\u00f3digo realiza la misma suma de tensores que antes, pero mediante la emisi\u00f3n:"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "musamrLavR5S"
      }
    },
    {
      "source": [
        "with tf.Graph().as_default():\n",
        "  # Create a six-element vector (1-D tensor).\n",
        "  primes = tf.constant([2, 3, 5, 7, 11, 13], dtype=tf.int32)\n",
        "\n",
        "  # Create a constant scalar with value 1.\n",
        "  ones = tf.constant(1, dtype=tf.int32)\n",
        "\n",
        "  # Add the two tensors. The resulting tensor is a six-element vector.\n",
        "  just_beyond_primes = tf.add(primes, ones)\n",
        "\n",
        "  with tf.Session() as sess:\n",
        "    print(just_beyond_primes.eval())"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "7lys_BeLy2SD",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " ## Producto de arreglos\n",
        "\n",
        "En \u00e1lgebra lineal, cuando se multiplican dos arreglos, la cantidad de *columnas* del primer arreglo debe ser igual a la cantidad de *filas* en el segundo arreglo.\n",
        "\n",
        "- Es **_v\u00e1lido_** para multiplicar un arreglo de `3 \u00d7 4` por uno de `4 \u00d7 2`. El resultado ser\u00e1 un arreglo de `3 \u00d7 2`.\n",
        "- Es **_inv\u00e1lido_** para multiplicar un arreglo de `4 \u00d7 2` por uno de `3 \u00d7 4`."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "it0P-AV0-Jb4"
      }
    },
    {
      "source": [
        "with tf.Graph().as_default():\n",
        "  # Create a matrix (2-d tensor) with 3 rows and 4 columns.\n",
        "  x = tf.constant([[5, 2, 4, 3], [5, 1, 6, -2], [-1, 3, -1, -2]],\n",
        "                  dtype=tf.int32)\n",
        "\n",
        "  # Create a matrix with 4 rows and 2 columns.\n",
        "  y = tf.constant([[2, 2], [3, 5], [4, 5], [1, 6]], dtype=tf.int32)\n",
        "\n",
        "  # Multiply `x` by `y`. \n",
        "  # The resulting matrix will have 3 rows and 2 columns.\n",
        "  matrix_multiply_result = tf.matmul(x, y)\n",
        "\n",
        "  with tf.Session() as sess:\n",
        "    print(matrix_multiply_result.eval())"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "OVR8QPif-MeS",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " ## Cambio de formas de tensores\n",
        "\n",
        "Dado que la suma de tensores y el producto de arreglos tienen restricciones en los operandos, los programadores de TensorFlow con frecuencia deben cambiar la forma de los tensores.\n",
        "\n",
        "Para cambiar la forma de un tensor, puedes usar el m\u00e9todo `tf.reshape`.\n",
        "Por ejemplo, puedes cambiar la forma de un tensor de 8 \u00d7 2 a uno de 2 \u00d7 8 o 4 \u00d7 4:"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "fziRnmuy-O9x"
      }
    },
    {
      "source": [
        "with tf.Graph().as_default():\n",
        "  # Create an 8x2 matrix (2-D tensor).\n",
        "  matrix = tf.constant([[1,2], [3,4], [5,6], [7,8],\n",
        "                        [9,10], [11,12], [13, 14], [15,16]], dtype=tf.int32)\n",
        "\n",
        "  # Reshape the 8x2 matrix into a 2x8 matrix.\n",
        "  reshaped_2x8_matrix = tf.reshape(matrix, [2,8])\n",
        "  \n",
        "  # Reshape the 8x2 matrix into a 4x4 matrix\n",
        "  reshaped_4x4_matrix = tf.reshape(matrix, [4,4])\n",
        "\n",
        "  with tf.Session() as sess:\n",
        "    print(\"Original matrix (8x2):\")\n",
        "    print(matrix.eval())\n",
        "    print(\"Reshaped matrix (2x8):\")\n",
        "    print(reshaped_2x8_matrix.eval())\n",
        "    print(\"Reshaped matrix (4x4):\")\n",
        "    print(reshaped_4x4_matrix.eval())"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "L05ob6a_G77m",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " \n",
        "Tambi\u00e9n puedes usar `tf.reshape` para cambiar la cantidad de dimensiones (la \"clasificaci\u00f3n\") del tensor.\n",
        "Por ejemplo, puedes cambiar la forma de un tensor de 8 \u00d7 2 a uno de 3-D de 2 \u00d7 2 \u00d7 4 o uno de 1-D de 16 elementos."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "b6cFa92YGyU5"
      }
    },
    {
      "source": [
        "with tf.Graph().as_default():\n",
        "  # Create an 8x2 matrix (2-D tensor).\n",
        "  matrix = tf.constant([[1,2], [3,4], [5,6], [7,8],\n",
        "                        [9,10], [11,12], [13, 14], [15,16]], dtype=tf.int32)\n",
        "\n",
        "  # Reshape the 8x2 matrix into a 3-D 2x2x4 tensor.\n",
        "  reshaped_2x2x4_tensor = tf.reshape(matrix, [2,2,4])\n",
        "  \n",
        "  # Reshape the 8x2 matrix into a 1-D 16-element tensor.\n",
        "  one_dimensional_vector = tf.reshape(matrix, [16])\n",
        "\n",
        "  with tf.Session() as sess:\n",
        "    print(\"Original matrix (8x2):\")\n",
        "    print(matrix.eval())\n",
        "    print(\"Reshaped 3-D tensor (2x2x4):\")\n",
        "    print(reshaped_2x2x4_tensor.eval())\n",
        "    print(\"1-D vector:\")\n",
        "    print(one_dimensional_vector.eval())"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "3MpcwWj9-Sqp",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " ### Ejercicio n.\u00ba 1: Cambia la forma de dos tensores para poder multiplicarlos.\n",
        "\n",
        "Los siguientes dos vectores son incompatibles para calcular el producto de arreglos:\n",
        "\n",
        "  *  `a = tf.constant([5, 3, 2, 7, 1, 4])`\n",
        "  *  `b = tf.constant([4, 6, 3])`\n",
        "\n",
        "Cambia la forma de estos vectores para que sean operandos compatibles y posibilitar el producto de arreglos.\n",
        "Luego, invoca una operaci\u00f3n de producto de arreglos en los tensores a los que les cambiaste la forma."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "CrpowaWo-VLq"
      }
    },
    {
      "source": [
        "  # Write your code for Task 1 here."
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "p6idvaeK-Zxq",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " ### Soluci\u00f3n\n",
        "\n",
        "Haz clic a continuaci\u00f3n para obtener una soluci\u00f3n."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "EYzU56M4MG_x"
      }
    },
    {
      "source": [
        "with tf.Graph().as_default(), tf.Session() as sess:\n",
        "  # Task: Reshape two tensors in order to multiply them\n",
        "  \n",
        "  # Here are the original operands, which are incompatible\n",
        "  # for matrix multiplication:\n",
        "  a = tf.constant([5, 3, 2, 7, 1, 4])\n",
        "  b = tf.constant([4, 6, 3])\n",
        "  # We need to reshape at least one of these operands so that\n",
        "  # the number of columns in the first operand equals the number\n",
        "  # of rows in the second operand.\n",
        "\n",
        "  # Reshape vector \"a\" into a 2-D 2x3 matrix:\n",
        "  reshaped_a = tf.reshape(a, [2,3])\n",
        "\n",
        "  # Reshape vector \"b\" into a 2-D 3x1 matrix:\n",
        "  reshaped_b = tf.reshape(b, [3,1])\n",
        "\n",
        "  # The number of columns in the first matrix now equals\n",
        "  # the number of rows in the second matrix. Therefore, you\n",
        "  # can matrix mutiply the two operands.\n",
        "  c = tf.matmul(reshaped_a, reshaped_b)\n",
        "  print(c.eval())\n",
        "\n",
        "  # An alternate approach: [6,1] x [1, 3] -> [6,3]"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "8Sef4d0SMMtk",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " ## Variables, Inicializaci\u00f3n y asignaci\u00f3n\n",
        "\n",
        "Hasta el momento, todas las operaciones que realizamos fueron en valores est\u00e1ticos (`tf.constant`); al invocar a `eval()`, el resultado fue siempre el mismo. TensorFlow permite definir objetos de `Variable`, cuyos valores pueden modificarse.\n",
        "\n",
        "Cuando se crea una variable, puedes establecer un valor inicial de forma expl\u00edcita o usar un inicializador (como una distribuci\u00f3n):"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "x1JYo7iE2oKk"
      }
    },
    {
      "source": [
        "g = tf.Graph()\n",
        "with g.as_default():\n",
        "  # Create a variable with the initial value 3.\n",
        "  v = tf.Variable([3])\n",
        "\n",
        "  # Create a variable of shape [1], with a random initial value,\n",
        "  # sampled from a normal distribution with mean 1 and standard deviation 0.35.\n",
        "  w = tf.Variable(tf.random_normal([1], mean=1.0, stddev=0.35))"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "6opLnjfD3PdL",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " Una particularidad de TensorFlow es que la **inicializaci\u00f3n de variables no es autom\u00e1tica**. Por ejemplo, el siguiente bloque generar\u00e1 un error:"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "qDYRXHTA4PTB"
      }
    },
    {
      "source": [
        "with g.as_default():\n",
        "  with tf.Session() as sess:\n",
        "    try:\n",
        "      v.eval()\n",
        "    except tf.errors.FailedPreconditionError as e:\n",
        "      print(\"Caught expected error: \", e)"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "d0OX1YRY5PTP",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " La forma m\u00e1s f\u00e1cil de inicializar una variable es invocando a `global_variables_initializer`. Ten en cuenta el uso de `Session.run()`, que es pr\u00e1cticamente equivalente a `eval()`."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "v7_aT7Hr5rnC"
      }
    },
    {
      "source": [
        "with g.as_default():\n",
        "  with tf.Session() as sess:\n",
        "    initialization = tf.global_variables_initializer()\n",
        "    sess.run(initialization)\n",
        "    # Now, variables can be accessed normally, and have values assigned to them.\n",
        "    print(v.eval())\n",
        "    print(w.eval())\n"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "z2lvhrxI5zJF",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " Una vez inicializadas, las variables mantendr\u00e1n su valor en la misma sesi\u00f3n (sin embargo, al iniciar una nueva sesi\u00f3n, deber\u00e1s volver a inicializarlas):"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "0GkYh7jf6JUd"
      }
    },
    {
      "source": [
        "with g.as_default():\n",
        "  with tf.Session() as sess:\n",
        "    sess.run(tf.global_variables_initializer())\n",
        "    # These three prints will print the same value.\n",
        "    print(w.eval())\n",
        "    print(w.eval())\n",
        "    print(w.eval())"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "_E8_lhS06IoV",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " Para cambiar el valor de una variable, usa el operando `assign`. Ten en cuenta que, con solo crear el operando `assign`, no se obtendr\u00e1 ning\u00fan efecto. Al igual que con la inicializaci\u00f3n, deber\u00e1s ejecutar el operando de asignaci\u00f3n para actualizar el valor de la variable:"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "yrZ31hPw66uy"
      }
    },
    {
      "source": [
        "with g.as_default():\n",
        "  with tf.Session() as sess:\n",
        "    sess.run(tf.global_variables_initializer())\n",
        "    # This should print the variable's initial value.\n",
        "    print(v.eval())\n",
        "\n",
        "    assignment = tf.assign(v, [7])\n",
        "    # The variable has not been changed yet!\n",
        "    print(v.eval())\n",
        "\n",
        "    # Execute the assignment op.\n",
        "    sess.run(assignment)\n",
        "    # Now the variable is updated.\n",
        "    print(v.eval())"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "zD0D1DCR7NBX",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " Hay muchos m\u00e1s temas sobre variables que no tratamos, como la carga y el almacenamiento. Para obtener m\u00e1s informaci\u00f3n, consulta los [documentos de TensorFlow](https://www.tensorflow.org/programmers_guide/variables)."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "tB78Zq4h78Zr"
      }
    },
    {
      "source": [
        " ### Ejercicio n.\u00ba 2: Simula 10 giros de dos dados.\n",
        "\n",
        "Crea una simulaci\u00f3n de dados, en la que se genere un tensor de 2-D de `10 \u00d7 3` con las siguientes caracter\u00edsticas:\n",
        "\n",
        "  * Que las columnas `1` y `2` incluyan una tirada de uno de los dados.\n",
        "  * Que la columna `3` incluya la suma de las columnas `1` y `2` en la misma fila.\n",
        "\n",
        "Por ejemplo, la primera fila puede tener los siguientes valores:\n",
        "\n",
        "  * La columna `1` incluye `4`\n",
        "  * La columna `2` incluye `3`\n",
        "  * La columna `3` incluye `7`\n",
        "\n",
        "Consulta la [documentaci\u00f3n de TensorFlow](https://www.tensorflow.org/api_guides/python/array_ops) para resolver esta tarea."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "iFIOcnfz_Oqw"
      }
    },
    {
      "source": [
        "# Write your code for Task 2 here."
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "ocwT0iXH-nhT",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " ### Soluci\u00f3n\n",
        "\n",
        "Haz clic a continuaci\u00f3n para obtener una soluci\u00f3n."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "Kt7aojXkR_qS"
      }
    },
    {
      "source": [
        "with tf.Graph().as_default(), tf.Session() as sess:\n",
        "  # Task 2: Simulate 10 throws of two dice. Store the results\n",
        "  # in a 10x3 matrix.\n",
        "\n",
        "  # We're going to place dice throws inside two separate\n",
        "  # 10x1 matrices. We could have placed dice throws inside\n",
        "  # a single 10x2 matrix, but adding different columns of\n",
        "  # the same matrix is tricky. We also could have placed\n",
        "  # dice throws inside two 1-D tensors (vectors); doing so\n",
        "  # would require transposing the result.\n",
        "  dice1 = tf.Variable(tf.random_uniform([10, 1],\n",
        "                                        minval=1, maxval=7,\n",
        "                                        dtype=tf.int32))\n",
        "  dice2 = tf.Variable(tf.random_uniform([10, 1],\n",
        "                                        minval=1, maxval=7,\n",
        "                                        dtype=tf.int32))\n",
        "\n",
        "  # We may add dice1 and dice2 since they share the same shape\n",
        "  # and size.\n",
        "  dice_sum = tf.add(dice1, dice2)\n",
        "\n",
        "  # We've got three separate 10x1 matrices. To produce a single\n",
        "  # 10x3 matrix, we'll concatenate them along dimension 1.\n",
        "  resulting_matrix = tf.concat(\n",
        "      values=[dice1, dice2, dice_sum], axis=1)\n",
        "\n",
        "  # The variables haven't been initialized within the graph yet,\n",
        "  # so let's remedy that.\n",
        "  sess.run(tf.global_variables_initializer())\n",
        "\n",
        "  print(resulting_matrix.eval())"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "6UUluecQSCvr",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    }
  ],
  "metadata": {
    "colab": {
      "default_view": {},
      "version": "0.3.2",
      "collapsed_sections": [
        "EYzU56M4MG_x",
        "Kt7aojXkR_qS",
        "copyright-notice"
      ],
      "name": "creating_and_manipulating_tensors.ipynb",
      "views": {}
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    }
  }
}
